#include <iostream>
using std::cout;
using std::endl;

class Point
{
public:
    Point(int ix = 0,int iy = 0)
    : _ix(ix)
    , _iy(iy)
    {
        cout << "Point(int=0,int=0)" << endl;
    }

    void print() const{
        cout << "(" << _ix
            << "," << _iy
            << ")" << endl;
    }

    ~Point(){
        cout << "~Point()" << endl; 
    }
private:
    int _ix;
    int _iy;
};

template <class T>
class RAII
{
public:
    //1.在构造函数中托管资源
    RAII(T * data)
    : _data(data)
    {
        cout << "RAII(T*)" << endl;
    }

    //2.析构函数中释放资源
    ~RAII(){
        if(_data){
            delete _data;
            _data = nullptr;
        }
        cout << "~RAII()" << endl;
    }

    //3.不允许复制赋值
    RAII(const RAII &) = delete;
    RAII& operator=(const RAII &) = delete;

    //4.提供访问资源的方法
    T * operator->(){
        return _data;
    }

    T & operator*(){
        return *_data;
    }
    
    //通过对象获取到裸指针
    T * get() const{
        return _data;
    }

    //重新接管新的资源
    void set(T * data){
        if(_data){
            delete _data;
            _data = nullptr;
        }
        _data = data;
    }
private:
    T * _data;
};

void test0(){
    RAII<int> raii(new int(10));

    RAII<Point> raii2(new Point(3,8));
    raii2->print();
    (*raii2.get()).print();

    raii2.set(new Point(4,5));
    (*raii2).print();

    int * p = new int(20);
    cout << *p << endl;
    delete p;

    Point * p2 = new Point(1,2);
    p2->print();
    (*p2).print();
    delete p2;
}

int main(void){
    test0();
    return 0;
}
